﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using Microsoft.Xna.Framework;

namespace Najak
{
	public partial class Scene
	{
		public class State
		{
			public string CurrentSceneName;
			public object SceneContent;
			public string StaticContent;

			public State(Scene scene)
			{
				CurrentSceneName = scene.Name;
				SceneContent = CaptureDynamicContent(scene);
				StaticContent = scene.GetStaticContent();
			}

			public State()
			{
			}

			public void Save()
			{
				SaveToFile(this);
			}


			static public Action<State> SaveToFile;
			static public Func<string, State> LoadFromFile;

			public void Apply(Scene scene, bool replaceCurrentContent)
			{
				// Load the scene and ensure all of the lines are the same length.
				int width;
				List<string> lines = new List<string>();
				SortedList<int, Portal.PortalTarget> portaldefs = new SortedList<int, Portal.PortalTarget>();

				if (replaceCurrentContent)
				{
					DynamicContentRegistry.Remove(scene.Name);
					DynamicContentRegistry.Add(scene.Name, SceneContent);
				}
				else
				{
					var t = SceneContent.GetType();
					if (!scene.HasDynamicContent)
						DynamicContentRegistry.Add(scene.Name, SceneContent);
				}

				using (StringReader reader = new StringReader(StaticContent))
				{
					string line = reader.ReadLine();
					width = line.Length;

					while (line != null)
					{
						lines.Add(line);
						if (line.Length != width)
							throw new Exception(String.Format("The length of line {0} is different from all preceeding lines.", lines.Count));
						line = reader.ReadLine();

						if (line == "===")
						{
							break;
						}
					}
					line = reader.ReadLine();

					int startinPortalID = 0;

					while (line != null)
					{
						int portalID = line[0] - '0';
						Portal.PortalTarget pd = new Portal.PortalTarget(line.Substring(2));
						portaldefs.Add(portalID, pd);
						if (portalID == scene.SendingPortal.Portal)
						{
							scene.StartingPortal = pd;
							startinPortalID = portalID;

							if (pd.IsCheckPoint)
							{
								App.Instance.CurrentCheckPoint = scene.SendingPortal;
							}
						}
						line = reader.ReadLine();
					}
					if (scene.StartingPortal == null)
					{
						scene.StartingPortal = portaldefs[0];
						scene.SendingPortal.Portal = startinPortalID;
					}
				}
				// Allocate the tile grid.
				scene.TileDimension = new Point(width, lines.Count);
				scene.Size = new Point(width * Tile.Size.X, lines.Count * Tile.Size.Y);
				scene._tiles = new Tile[scene.TileDimension.X, scene.TileDimension.Y];

				for (int row = 0; row < scene.Height; ++row)
				{	// load the tiles now
					for (int column = 0; column < scene.Width; ++column)
					{
						// to load each tile.
						char tileType = lines[row][column];
						if (scene._tiles[column, row] == null)
						{
							Tile t = scene.LoadTile(tileType, column, row, portaldefs);
							if (t != null)
							{
								scene.SetTile(t, new Coordinate(column, row));
								//_tiles[x, y] = t;
								//t.LoadContent(this);
								//       t.OnAdded(this, x, y);
							}
						}
					}
				}
				if (scene.HasDynamicContent)
				{
					object dc;
					DynamicContentRegistry.TryGetValue(scene.Name, out dc);

					ApplyDynamicContent(scene, dc);

					//foreach (Info info in dc)
					//{
					//   info.Create(scene);
					//}
				}
				scene.TrimSize();
			}

			static public Action<Scene, object> ApplyDynamicContent;

		}
	}
}
